from openai import OpenAI
import logging
import httpx
from utils.timeit import timeit
from .llm_logger import LLMLogger

logging.basicConfig(
    level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s\n"
)

class MapAgent:
    def log_response(self, response: httpx.Response) -> httpx.Response:
        """同步处理HTTP响应钩子"""
        try:
            print("DEBUG: Processing response hook")
            # 确保响应内容已读取
            if not hasattr(response, "_content"):
                response.read()
            # 保存响应体副本
            response._content = response.content
            self.llm_logger.log(response.request, response)
        except Exception as e:
            logging.error(f"Error in log_response: {str(e)}")
        return response

    @timeit
    def __init__(self):
        # 创建日志记录器
        self.llm_logger = LLMLogger()

        custom_client = httpx.Client(
            trust_env=False,         # 忽略系统代理环境变量
            timeout=30.0,            # 请求超时时间
            limits=httpx.Limits(     # 连接池配置
                max_connections=100,  # 最大连接数
                max_keepalive_connections=20,  # 保持活跃的连接数
                keepalive_expiry=300  # 保持连接时间(秒)
            ),
            http2=True,              # 启用HTTP/2
            event_hooks={
                'response': [self.log_response]
            }
        )

        self.client = OpenAI(
            base_url='http://localhost:11434/v1',
            api_key='ollama',
            http_client=custom_client
        )

        self.agent_cards = {}

        self._system_message = {
            'role': 'system',
            'content': """**角色**：你是一个专业的餐厅推荐助手，利用高德MCP API获取餐厅数据，并根据评分、距离和人均消费筛选最佳选择。

**工作流程（分步执行）：**
1. **用户需求解析**
   - 获取用户的【用餐地点】（如“北京中关村”，“上海陆家嘴”）
   - 获取用户的【偏好筛选】（如“川菜”，“人均100-200元”）

2. **调用高德MCP进行查询**
   - 使用maps_geo获取地点的经纬度（由于你的经纬度信息可能有误，因此，请使用高德MCP获取经纬度信息）
   - 根据经纬度获取附近的餐厅信息，只搜索附近1000米范围，如果搜索不到则视作没有合适的推荐
   备注1：工具只能按照前面顺序调用，每个工具调用一次，然后结束工具调用
   备注2：如果得到多个经纬度，使用第一个经纬度

3. **数据处理与排序**
   - 从返回的餐厅列表中提取：
     ✅ 名称 | ✅ 地址 | ✅ 评分（如4.8） | ✅ 人均（如150元） | ✅ 联系电话等
   - **按评分降序排序**，若评分相同则按距离升序排序

4. **返回Top5推荐列表**
   - 请输出json格式结果，格式示例如下：
     ```json
     {
         "finish": "true",
         "pois": [
             {
                 "id": "B0G2AOCJ0D",
                 "name": "Little RAC(国金中心二期店)",
                 "address": "世纪大道8号LG2-B9(陆家嘴地铁站6号口旁)",
                 "photo": "https://xxx.jpg",
                 "phone": "153xxxxxxxx",
                 "cost": "150",
                 "rating": "4.5",
                 "distance": "1500",
                 "open_time": "8:00-18:00",
                 "meal_ordering: "1"
             },
         ]
     }
     ```
     其中，finish：是否完成餐厅选择，meal_ordering：是否支持预定，open_time：营业时间，rating：评分，cost：人均消费，
   - json格式需要严格匹配，内容不能缺失，必须包含finish字段，pois中必须包含id、name、address、photo、phone、cost、rating、distance、open_time、meal_ordering字段
   - 如果高德MCP返回的信息没有对应字段，则json格式对应字段保留空字符串
   - 如果搜索结果小于5家，那么就按照实际搜索到的结果推荐返回
"""
        }

        self.messages = [self._system_message]

    @timeit
    def invoke(self, input_string: str, tools) -> str:

        self.messages.append(
            {
                'role': 'user',
                'content': input_string + "/no_think",
            }
        )

        logging.info(f"start invoke LLM: {self.messages}, {tools}\n")
        chat_completion = self.client.chat.completions.create(
            # Gemma does not support tool calling. model="gemma3:12b",
            # model="qwen2.5:7b",
            # Another option, but slower
            model="qwen3:8b",
            # model="qwen2.5:7b",
            messages=self.messages,
            tools=tools,
            temperature=0
        )
        logging.info(f"finish invoke LLM: {chat_completion}\n")

        return chat_completion

    def add_message(self, message: str):
        self.messages.append(
            {
                'role': 'user',
                'content': message,
            }
        )